package com.current.game.three.service;

import java.util.Random;

/**
 * @author baopan
 * @createTime 2024/6/2 23:51
 */
public class ThreeValueServiceImpl {

    public void doRandom(int[][] ttfJValue) {
        int random = new Random().nextInt(16);
        int zeroCount = 0;
        while (true) {
            boolean hasEmpty = false;
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (ttfJValue[i][j] == 0) {
                        hasEmpty = true;
                        if (zeroCount == random) {
                            ttfJValue[i][j] = 2;
                            return;
                        }
                        zeroCount++;
                    }
                }
            }
            if (!hasEmpty) {
                return;
            }
        }

    }

    public void doUp(int[][] ttfJValue) {
        int[][] temps = copyTTFValue(ttfJValue);
        doCalValues(ttfJValue, 0, 0, 0, 3);
        doCalValues(ttfJValue, 1, 0, 1, 3);
        doCalValues(ttfJValue, 2, 0, 2, 3);
        doCalValues(ttfJValue, 3, 0, 3, 3);

        boolean self = isSelf(ttfJValue, temps);
        if (!self) {
            doRandom(ttfJValue);
        }
    }

    public void doDown(int[][] ttfJValue) {
        int[][] temps = copyTTFValue(ttfJValue);
        doCalValues(ttfJValue, 0, 3, 0, 0);
        doCalValues(ttfJValue, 1, 3, 1, 0);
        doCalValues(ttfJValue, 2, 3, 2, 0);
        doCalValues(ttfJValue, 3, 3, 3, 0);

        boolean self = isSelf(ttfJValue, temps);
        if (!self) {
            doRandom(ttfJValue);
        }
    }


    public void doLeft(int[][] ttfJValue) {//
        int[][] temps = copyTTFValue(ttfJValue);
        doCalValues(ttfJValue, 0, 0, 3, 0);
        doCalValues(ttfJValue, 0, 1, 3, 1);
        doCalValues(ttfJValue, 0, 2, 3, 2);
        doCalValues(ttfJValue, 0, 3, 3, 3);

        boolean self = isSelf(ttfJValue, temps);
        if (!self) {
            doRandom(ttfJValue);
        }
    }

    public void doRight(int[][] ttfJValue) {//
        int[][] temps = copyTTFValue(ttfJValue);
        doCalValues(ttfJValue, 3, 0, 0, 0);
        doCalValues(ttfJValue, 3, 1, 0, 1);
        doCalValues(ttfJValue, 3, 2, 0, 2);
        doCalValues(ttfJValue, 3, 3, 0, 3);

        boolean self = isSelf(ttfJValue, temps);
        if (!self) {
            doRandom(ttfJValue);
        }
    }

    private boolean isSelf(int[][] ttfJValue, int[][] originValue) {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (ttfJValue[i][j] != originValue[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

    private int[][] copyTTFValue(int[][] ttfJValue) {
        int[][] result = new int[4][4];
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                result[i][j] = ttfJValue[i][j];
            }
        }
        return result;
    }


    private void doCalValues(int[][] values, int startI, int startJ, int endI, int endJ) {
        if (startI == endI) {
            if (startJ < endJ) {//向下
                int[] temps = mergeAndSort(values[startI][0], values[startI][1], values[startI][2], values[startI][3]);
                values[startI][0] = temps[0];
                values[startI][1] = temps[1];
                values[startI][2] = temps[2];
                values[startI][3] = temps[3];
            } else {//向上
                int[] temps = mergeAndSort(values[startI][3], values[startI][2], values[startI][1], values[startI][0]);
                values[startI][3] = temps[0];
                values[startI][2] = temps[1];
                values[startI][1] = temps[2];
                values[startI][0] = temps[3];
            }
            return;
        }
        if (startJ == endJ) {
            if (startI < endI) {//向左
                int[] temps = mergeAndSort(values[0][startJ], values[1][startJ], values[2][startJ], values[3][startJ]);
                values[0][startJ] = temps[0];
                values[1][startJ] = temps[1];
                values[2][startJ] = temps[2];
                values[3][startJ] = temps[3];
            } else {//向右
                int[] temps = mergeAndSort(values[3][startJ], values[2][startJ], values[1][startJ], values[0][startJ]);
                values[3][startJ] = temps[0];
                values[2][startJ] = temps[1];
                values[1][startJ] = temps[2];
                values[0][startJ] = temps[3];
            }
            return;
        }
    }

    private int[] mergeAndSort(int one, int two, int third, int four) {
        int[] column = new int[]{one, two, third, four};

        // 将非零元素向左滑动
        int k = 0;
        for (int i = 0; i < 4; i++) {
            if (column[i] != 0) {
                column[k++] = column[i];
            }
        }
        // 将剩余位置填充为0（如果需要）
        while (k < 4) {
            column[k++] = 0;
        }


        for (int i = 0; i < 4 - 1; i++) {
            if (column[i] == column[i + 1]) {
                column[i] *= 2; // 合并相同的数字
                column[i + 1] = 0; // 将下一个位置设置为0，表示已经合并

            }
        }

        // 将非零元素向左滑动
        int j = 0;
        for (int i = 0; i < 4; i++) {
            if (column[i] != 0) {
                column[j++] = column[i];
            }
        }

        // 将剩余位置填充为0（如果需要）
        while (j < 4) {
            column[j++] = 0;
        }

        return column;
    }
}
